import {PluginCommand} from "./PluginCommand";
import {PluginCADToolFunctionType} from "../../nodeApp/static/lib/crowncad-plugin-sdk-0.0.1";
import {savedXMLAssemFidsApi, searchSavedXMLAssemInfo, saveXMLApi} from "../util/request/flightSimulationApi";

const xml2js = require('xml2js');

class FlightControlSimulationCommand extends PluginCommand {
  constructor() {
    super();
  }

  assemblyInfo = {};
  mateFeature = [];
  xmlFileParserString = "";

  openLoading(text = "") {
    if (this.toolQuery) {
      this.toolQuery.openLoading(text);
    }
  }

  getPercentage(cb){
    if (this.request) {
      this.request.execFunction(PluginCADToolFunctionType.GETPERCENTAGE).then(res => {
        if (res?.code === 200) {
          cb(res?.data?.percentage)
        }
      });
    }
  }
  getAssemblyInfo(cb) {
    if (this.request) {
      this.request.execFunction(PluginCADToolFunctionType.GETASSEMBLYINFO).then(res => {
        if (res?.code === 200) {
          this.assemblyInfo = {};
          this.mateFeature = [];
          this.assemblyInfo = JSON.parse(res?.data?.assemblyInfo);
          this.mateFeature = JSON.parse(res?.data?.mateFeature);
          cb(this.assemblyInfo, this.mateFeature)
        }
      });
    }
  }

  /**
   * 获取XML信息
   */
  getSimulationInfo() {
    if (this.request) {
      this.request.execFunction(PluginCADToolFunctionType.GETSIMULATIONINFO, this.commandId).then(res => {
        if (res?.code === 200) {
          //创建xml
          let obj = JSON.parse(res?.data?.simulation);
          this.eventBusAlertMsg('XML文件导出成功！','success');
          this.createXML(obj);
        }
        this.closeLoading();
      });
    }
  }

  /**
   * 根据xml内容解析，设置stl文件的名字
   */
  setFileName(fileInfo) {
    if (this.request) {
      this.request.execFunction(PluginCADToolFunctionType.SETFILENAME,{stlFileName:fileInfo}).then(res => {
      });
    }
  }
  setIsExportSTL(val) {
    if (this.request) {
      this.request.execFunction(PluginCADToolFunctionType.EXPORTSTL,{isExportStl:val}).then(res => {
        if (res?.data.stlExportStatus === true){
          this.eventBusAlertMsg('STL文件导出成功！','success');
        }
      });
    }
  }
  createXMLFromDataBase(){
    if(this.xmlFileParserString === ""){
      this.eventBusAlertMsg('不存在相关数据，无法导出XML文件！','warning');
    }else {
      //下载xml
      this.downLoadXML(this.xmlFileParserString);
    }
  }

  /**
   * 生成xml
   */
  createXML(data) {
    const builder = new xml2js.Builder({
      rootName: 'SimscapeMultibodyImportXML'
    });
    const xmlContent = builder.buildObject(data);
    console.log(xmlContent);
    this.downLoadXML(xmlContent);
  }

  /**
   * xml文件下载
   */
  downLoadXML(data) {
    const blob = new Blob([data], {type: 'application/xml'});
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.setAttribute('download', this.assemblyInfo?.document?.aliasName + '.xml')
    document.body.appendChild(link);
    link.click();
    // 释放 URL 对象
    document.body.removeChild(link);
    URL.revokeObjectURL(link.href);
  }

  /**
   * 读取xml文件
   */
  readXmlFile(file) {
    //通过文档名判断xml和装配文档是否相同
    let str = file.name;
    let newStr = str.replace(/\.xml$/, '');
    if (this.assemblyInfo.document.name === newStr) {
      let assemblyFid = this.assemblyInfo.documentId;
      let assemblyFName = this.assemblyInfo.document.name;
      let xmlFid = file?.raw?.uid;
      let xmlFile = file?.raw;
      this.saveXML(assemblyFid, assemblyFName, xmlFid, xmlFile)
      
      // if (this.isPartsMatched(file)) {
      //
      // } else {
      //   this.eventBusAlertMsg('当前装配文件与xml文件不匹配，请检查', 'error');
      // }
    } else {
      this.eventBusAlertMsg('当前装配文件与xml文件不匹配，请检查', 'error');
    }
  }

  /**
   * 根据xml的part和装配文档是否匹配
   */
  async isPartsMatched(file) {
    let xmlString = await this.readXML(file);
    this.xmlStringAnalysis(xmlString);
  }

  async readXML(file) {
    return new Promise(async resolve => {
      let reader = new FileReader();
      reader.readAsText(file.raw);
      let fileString = null;
      reader.onload = (e) => {
        fileString = e.target.result;
        resolve(fileString);
      }
    })
  }

  /**
   * xml文件内容解析
   */
  xmlStringAnalysis(xmlString) {
    let parser = new DOMParser();
    let xmlDoc = parser.parseFromString(xmlString, "application/xml");

    let nameList = [];
    let partNodes = xmlDoc.getElementsByTagName("Part");
    for (let i = 0; i < partNodes.length; i++) {
      let name = partNodes[i].getAttribute('name');
      nameList.push(name);
    }
    //todo 根据零件名判断是否xml与装配文档匹配
    console.log(nameList);
  }

  /**
   * 将xml与assembly文件关联，存储xml数据在数据库中
   */
  saveXML(assemblyFid, assemblyFName, xmlFid, xmlFile) {
    let formData = new FormData();
    formData.append('assemblyFid', assemblyFid ?? "");
    formData.append('assemblyFName', assemblyFName ?? "");
    formData.append('xmlFid', xmlFid ?? "");
    formData.append('xmlFile', xmlFile ?? "");
    saveXMLApi(formData).then(res => {
      if (res?.status === 200) {
        if (res.data) {
          this.eventBusAlertMsg(res.data, 'success');
        }
      } else {
        this.eventBusAlertMsg('文件存储失败，请重新上传', 'error');
      }
    })
  }

  /**
   * 查找当前装配文档存在数据库的xml数据
   */
  searchSavedXMLAssemInfo() {
    let assemblyFid = this.assemblyInfo.documentId;
    let formData = new FormData();
    formData.append('assemblyFid', assemblyFid ?? "");
    searchSavedXMLAssemInfo(formData).then(res => {
      if (res?.status === 200) {
        if (res?.data === '') {
          this.xmlFileParserString = "";
        } else {
          this.xmlFileParserString = "" ;
          this.xmlFileParserString = res?.data?.xmlFile ;
          const parser = new DOMParser();
          let xmlDoc = parser.parseFromString(res?.data?.xmlFile, "application/xml");

          let GeometryFiles = [];
          let partNodes = xmlDoc.getElementsByTagName("Part");
          for (let i = 0; i < partNodes.length; i++) {
            let partName = partNodes[i].getAttribute('name');
            let GeometryFile = partNodes[i].getElementsByTagName("GeometryFile");
            for (let j = 0; j < GeometryFile.length; j++) {
              let geometryName = GeometryFile[j].getAttribute('name');
              let stlInfo = {
                partName: partName,
                geometryName: geometryName
              }
              GeometryFiles.push(stlInfo);
            }
          }
          this.setFileName(GeometryFiles);
        }
      }
    })
  }
}

const flightControlSimulationCommand = new FlightControlSimulationCommand();
export {flightControlSimulationCommand};